<template>
  <div class="role-container">
    <!-- 搜索区域 -->
    <el-card shadow="hover" class="search-card">
      <el-form :model="searchForm" :inline="true" class="search-form">
        <el-form-item label="角色名称">
          <el-input
            v-model="searchForm.roleName"
            placeholder="请输入角色名称"
            clearable
            style="width: 200px"
            @keyup.enter="handleSearch"
          >
            <template #prefix>
              <el-icon><Search /></el-icon>
            </template>
          </el-input>
        </el-form-item>

        <el-form-item label="创建时间">
          <el-date-picker
            v-model="dateRange"
            type="daterange"
            range-separator="至"
            start-placeholder="开始日期"
            end-placeholder="结束日期"
            format="YYYY-MM-DD"
            value-format="YYYY-MM-DD"
            style="width: 240px"
          />
        </el-form-item>

        <el-form-item>
          <el-button type="primary" :icon="Search" @click="handleSearch">
            搜索
          </el-button>
          <el-button :icon="Refresh" @click="handleReset">
            重置
          </el-button>
        </el-form-item>
      </el-form>
    </el-card>

    <!-- 主要内容区域 -->
    <el-card shadow="hover" class="main-card">
      <template #header>
        <div class="card-header">
          <h3>角色管理</h3>
          <div class="header-buttons">
            <el-button
              type="danger"
              :icon="Delete"
              :disabled="selectedRoles.length === 0"
              @click="handleBatchDelete"
            >
              批量删除
            </el-button>
            <el-button type="primary" :icon="Plus" @click="handleAdd">
              新增角色
            </el-button>
          </div>
        </div>
      </template>

      <!-- 角色表格 -->
      <el-table
          v-loading="loading"
          :data="roleList"
          stripe
          border
          style="width: 100%"
          @selection-change="handleSelectionChange"
      >
        <el-table-column type="selection" width="50" align="center" />

        <el-table-column type="index" label="#" width="50" align="center" />

        <el-table-column prop="id" label="ID" width="70" align="center" />

        <el-table-column prop="roleName" label="角色名称" width="140" align="center" />

        <el-table-column prop="roleDesc" label="角色描述" min-width="130" show-overflow-tooltip />

        <el-table-column prop="createTime" label="创建时间" width="160" align="center">
          <template #default="{ row }">
            {{ formatDate(row.createTime) }}
          </template>
        </el-table-column>

        <el-table-column prop="updateTime" label="更新时间" width="160" align="center">
          <template #default="{ row }">
            {{ formatDate(row.updateTime) }}
          </template>
        </el-table-column>

        <el-table-column label="操作" width="240" align="center" fixed="right">
          <template #default="{ row }">
            <el-button
                type="warning"
                size="small"
                :icon="Setting"
                @click="handleAssignPermissions(row)"
            >
              分配权限
            </el-button>
            <el-button
                type="primary"
                size="small"
                :icon="Edit"
                @click="handleEdit(row)"
            >
              编辑
            </el-button>
            <el-button
                type="danger"
                size="small"
                :icon="Delete"
                @click="handleDelete(row)"
            >
              删除
            </el-button>
          </template>
        </el-table-column>
      </el-table>


      <!-- 分页 -->
      <div class="pagination-container">
        <el-pagination
          v-model:current-page="searchForm.page"
          v-model:page-size="searchForm.limit"
          :page-sizes="[10, 20, 50, 100]"
          :total="total"
          layout="total, sizes, prev, pager, next, jumper"
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
        />
      </div>
    </el-card>

    <!-- 角色表单对话框 -->
    <el-dialog
      v-model="dialogVisible"
      :title="dialogTitle"
      width="600px"
      :close-on-click-modal="false"
    >
      <el-form
        ref="roleFormRef"
        :model="roleForm"
        :rules="formRules"
        label-width="80px"
        class="role-form"
      >
        <el-form-item label="角色名称" prop="roleName">
          <el-input
            v-model="roleForm.roleName"
            placeholder="请输入角色名称"
          />
        </el-form-item>

        <el-form-item label="角色描述" prop="roleDesc">
          <el-input
            v-model="roleForm.roleDesc"
            type="textarea"
            :rows="4"
            placeholder="请输入角色描述"
          />
        </el-form-item>
      </el-form>

      <template #footer>
        <span class="dialog-footer">
          <el-button @click="dialogVisible = false">取消</el-button>
          <el-button type="primary" :loading="submitLoading" @click="handleSubmit">
            确定
          </el-button>
        </span>
      </template>
    </el-dialog>

    <!-- 分配权限对话框 -->
    <el-dialog
      v-model="permissionDialogVisible"
      title="分配权限"
      width="800px"
      :close-on-click-modal="false"
      @opened="onPermissionDialogOpened"
    >
      <div class="permission-dialog-content">
        <div class="permission-info">
          <p><strong>角色名称：</strong>{{ currentRole?.roleName }}</p>
          <p><strong>角色描述：</strong>{{ currentRole?.roleDesc || '无' }}</p>
        </div>

        <el-divider />

        <div class="permission-tree-container">
          <div class="permission-tree-header">
            <span>权限列表</span>
            <div class="tree-actions">
              <el-button size="small" @click="expandAll">全部展开</el-button>
              <el-button size="small" @click="collapseAll">全部收起</el-button>
              <el-button size="small" type="primary" @click="checkAll">全选</el-button>
              <el-button size="small" @click="uncheckAll">取消全选</el-button>
            </div>
          </div>

          <el-tree
            ref="permissionTreeRef"
            v-loading="permissionLoading"
            :data="permissionTree"
            :props="treeProps"
            node-key="id"
            show-checkbox
            check-strictly
            :expanded-keys="expandedKeys"
            :checked-keys="checkedKeys"
            class="permission-tree"
          >
            <template #default="{ node, data }">
              <span class="tree-node">
                <el-icon v-if="data.type === 'menu'" class="node-icon">
                  <Folder />
                </el-icon>
                <el-icon v-else class="node-icon">
                  <Document />
                </el-icon>
                <span class="node-label">{{ node.label }}</span>
                <el-tag
                  :type="data.type === 'menu' ? 'primary' : 'success'"
                  size="small"
                  class="node-tag"
                >
                  {{ data.type === 'menu' ? '菜单' : '按钮' }}
                </el-tag>
              </span>
            </template>
          </el-tree>
        </div>
      </div>

      <template #footer>
        <span class="dialog-footer">
          <el-button @click="permissionDialogVisible = false">取消</el-button>
          <el-button
            type="primary"
            :loading="permissionSubmitLoading"
            @click="handlePermissionSubmit"
          >
            确定
          </el-button>
        </span>
      </template>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
  import { ref, reactive, onMounted, computed, nextTick } from 'vue'
  import { ElMessage, ElMessageBox, ElTree, type FormInstance, type FormRules } from 'element-plus'
  import {
    Search,
    Refresh,
    Plus,
    Edit,
    Delete,
    Setting,
    Folder,
    Document
  } from '@element-plus/icons-vue'

  // 导入API和类型
  import {
    getRoleListAPI,
    addRoleAPI,
    updateRoleAPI,
    deleteRoleAPI,
    batchDeleteRoleAPI,
    getPermissionTreeAPI,
    assignRolePermissionsAPI,
    getRolePermissionsAPI
  } from '@/api/system/role/role.ts'
  import type {
    RoleInfo,
    RoleSearchParams,
    RoleFormData,
    PermissionInfo,
    RolePermissionsData
  } from '@/api/system/role/types.ts'

  // 响应式数据
  const loading = ref(false)
  const submitLoading = ref(false)
  const permissionLoading = ref(false)
  const permissionSubmitLoading = ref(false)
  const roleList = ref<RoleInfo[]>([])
  const permissionTree = ref<PermissionInfo[]>([])
  const selectedRoles = ref<RoleInfo[]>([])
  const currentRole = ref<RoleInfo | null>(null)
  const total = ref(0)
  const dialogVisible = ref(false)
  const permissionDialogVisible = ref(false)
  const isEdit = ref(false)
  const roleFormRef = ref<FormInstance>()
  const permissionTreeRef = ref<InstanceType<typeof ElTree>>()

  // 搜索表单
  const searchForm = reactive<RoleSearchParams>({
    page: 1,
    limit: 10,
    roleName: ''
  })

  // 日期范围
  const dateRange = ref<[string, string] | null>(null)

  // 角色表单
  const roleForm = reactive<RoleFormData>({
    roleName: '',
    roleDesc: ''
  })

  // 权限树配置
  const treeProps = {
    children: 'children',
    label: 'permissionName'
  }

  const expandedKeys = ref<number[]>([])
  const checkedKeys = ref<number[]>([])

  // 表单验证规则
  const formRules: FormRules = {
    roleName: [
      { required: true, message: '请输入角色名称', trigger: 'blur' },
      { min: 2, max: 20, message: '角色名称长度在 2 到 20 个字符', trigger: 'blur' }
    ]
  }

  // 计算属性
  const dialogTitle = computed(() => isEdit.value ? '编辑角色' : '新增角色')

  // 方法
  const formatDate = (dateString: string) => {
    if (!dateString) return '-'
    return new Date(dateString).toLocaleString('zh-CN')
  }

  // 获取角色列表
  const getRoleList = async () => {
    loading.value = true
    try {
      // 处理日期范围
      if (dateRange.value) {
        searchForm.startTime = dateRange.value[0]
        searchForm.endTime = dateRange.value[1]
      } else {
        searchForm.startTime = undefined
        searchForm.endTime = undefined
      }

      const response = await getRoleListAPI(searchForm)
      if (response.code === 200) {
        roleList.value = response.data.list
        total.value = response.data.total
      } else {
        ElMessage.error(response.message)
      }
    } catch (error) {
      console.error('获取角色列表失败:', error)
      ElMessage.error('获取角色列表失败')
    } finally {
      loading.value = false
    }
  }

  // 获取权限树
  const getPermissionTree = async () => {
    permissionLoading.value = true
    try {
      const response = await getPermissionTreeAPI()
      if (response.code === 200) {
        permissionTree.value = response.data
      } else {
        ElMessage.error(response.message)
      }
    } catch (error) {
      console.error('获取权限树失败:', error)
      ElMessage.error('获取权限树失败')
    } finally {
      permissionLoading.value = false
    }
  }

  // 搜索
  const handleSearch = () => {
    searchForm.page = 1
    getRoleList()
  }

  // 重置
  const handleReset = () => {
    Object.assign(searchForm, {
      page: 1,
      limit: 10,
      roleName: ''
    })
    dateRange.value = null
    getRoleList()
  }

  // 分页
  const handleSizeChange = (size: number) => {
    searchForm.limit = size
    searchForm.page = 1
    getRoleList()
  }

  const handleCurrentChange = (page: number) => {
    searchForm.page = page
    getRoleList()
  }

  // 选择变化
  const handleSelectionChange = (selection: RoleInfo[]) => {
    selectedRoles.value = selection
  }

  // 重置表单
  const resetForm = () => {
    Object.assign(roleForm, {
      roleName: '',
      roleDesc: ''
    })
    roleFormRef.value?.clearValidate()
  }

  // 新增角色
  const handleAdd = () => {
    resetForm()
    isEdit.value = false
    dialogVisible.value = true
  }

  // 编辑角色
  const handleEdit = (row: RoleInfo) => {
    resetForm()
    isEdit.value = true
    Object.assign(roleForm, {
      id: row.id,
      roleName: row.roleName,
      roleDesc: row.roleDesc
    })
    dialogVisible.value = true
  }

  // 提交表单
  const handleSubmit = async () => {
    if (!roleFormRef.value) return

    try {
      await roleFormRef.value.validate()
      submitLoading.value = true

      const api = isEdit.value ? updateRoleAPI : addRoleAPI
      const response = await api(roleForm)

      if (response.code === 200) {
        ElMessage.success(isEdit.value ? '更新成功' : '添加成功')
        dialogVisible.value = false
        getRoleList()
      } else {
        ElMessage.error(response.message)
      }
    } catch (error) {
      console.error('提交失败:', error)
    } finally {
      submitLoading.value = false
    }
  }

  // 删除角色
  const handleDelete = async (row: RoleInfo) => {
    try {
      await ElMessageBox.confirm(
        `确定要删除角色 "${row.roleName}" 吗？`,
        '删除确认',
        {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }
      )

      const response = await deleteRoleAPI(row.id)
      if (response.code === 200) {
        ElMessage.success('删除成功')
        getRoleList()
      } else {
        ElMessage.error(response.message)
      }
    } catch (error) {
      if (error !== 'cancel') {
        ElMessage.error('删除失败')
      }
    }
  }

  // 批量删除
  const handleBatchDelete = async () => {
    if (selectedRoles.value.length === 0) {
      ElMessage.warning('请选择要删除的角色')
      return
    }

    try {
      await ElMessageBox.confirm(
        `确定要删除选中的 ${selectedRoles.value.length} 个角色吗？`,
        '批量删除确认',
        {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }
      )

      const ids = selectedRoles.value.map(role => role.id)
      const response = await batchDeleteRoleAPI({ ids })

      if (response.code === 200) {
        ElMessage.success('批量删除成功')
        getRoleList()
      } else {
        ElMessage.error(response.message)
      }
    } catch (error) {
      if (error !== 'cancel') {
        ElMessage.error('批量删除失败')
      }
    }
  }

  // 分配权限
  const handleAssignPermissions = async (row: RoleInfo) => {
    currentRole.value = row

    // 先获取权限树
    await getPermissionTree()

    // 获取角色已有权限
    try {
      const response = await getRolePermissionsAPI(row.id)
      if (response.code === 200) {
        console.log('获取到的角色权限:', response.data)
        checkedKeys.value = response.data

        // 等待DOM更新后设置选中状态
        await nextTick()

        // 设置权限树的选中状态
        if (permissionTreeRef.value) {
          permissionTreeRef.value.setCheckedKeys(response.data, false)
          console.log('已设置权限树选中状态:', response.data)
        }
      }
    } catch (error) {
      console.error('获取角色权限失败:', error)
    }

    permissionDialogVisible.value = true
  }

  // 权限树操作方法
  const expandAll = () => {
    const allKeys = getAllNodeKeys(permissionTree.value)
    expandedKeys.value = allKeys
  }

  const collapseAll = () => {
    expandedKeys.value = []
  }

  const checkAll = () => {
    const allKeys = getAllNodeKeys(permissionTree.value)
    checkedKeys.value = allKeys
    permissionTreeRef.value?.setCheckedKeys(allKeys, false)
  }

  const uncheckAll = () => {
    checkedKeys.value = []
    permissionTreeRef.value?.setCheckedKeys([], false)
  }

  // 获取所有节点的key
  const getAllNodeKeys = (nodes: PermissionInfo[]): number[] => {
    const keys: number[] = []
    const traverse = (nodes: PermissionInfo[]) => {
      nodes.forEach(node => {
        keys.push(node.id)
        if (node.children && node.children.length) {
          traverse(node.children)
        }
      })
    }
    traverse(nodes)
    return keys
  }

  // 对话框打开后的回调
  const onPermissionDialogOpened = async () => {
    console.log('权限对话框已打开，重新设置选中状态')

    // 确保DOM完全渲染后再设置选中状态
    await nextTick()

    if (permissionTreeRef.value && checkedKeys.value.length > 0) {
      // 重新设置选中状态
      permissionTreeRef.value.setCheckedKeys(checkedKeys.value, false)
      console.log('对话框打开后重新设置选中状态:', checkedKeys.value)

      // 自动展开已选中节点的父节点
      const expandKeys = getParentKeys(permissionTree.value, checkedKeys.value)
      expandedKeys.value = [...new Set([...expandedKeys.value, ...expandKeys])]
    }
  }

  // 获取选中节点的所有父节点ID
  const getParentKeys = (nodes: PermissionInfo[], checkedKeys: number[]): number[] => {
    const parentKeys: number[] = []

    const findParents = (nodes: PermissionInfo[], targetIds: number[], parentId: number = 0) => {
      nodes.forEach(node => {
        if (targetIds.includes(node.id) && parentId !== 0) {
          parentKeys.push(parentId)
        }

        if (node.children && node.children.length > 0) {
          // 检查子节点是否有选中的
          const hasCheckedChild = node.children.some(child =>
            targetIds.includes(child.id) ||
            (child.children && hasCheckedInChildren(child.children, targetIds))
          )

          if (hasCheckedChild) {
            parentKeys.push(node.id)
          }

          findParents(node.children, targetIds, node.id)
        }
      })
    }

    const hasCheckedInChildren = (children: PermissionInfo[], targetIds: number[]): boolean => {
      return children.some(child =>
        targetIds.includes(child.id) ||
        (child.children && hasCheckedInChildren(child.children, targetIds))
      )
    }

    findParents(nodes, checkedKeys)
    return parentKeys
  }

  let data = reactive<RolePermissionsData>({
    roleId:'',
    permissionIds:[]
  })

  // 提交权限分配
  const handlePermissionSubmit = async () => {
    if (!currentRole.value) return

    try {
      permissionSubmitLoading.value = true
      const checkedNodes = permissionTreeRef.value?.getCheckedKeys(false) as number[]
      const halfCheckedNodes = permissionTreeRef.value?.getHalfCheckedKeys() as number[]
      const allCheckedNodes = [...checkedNodes, ...halfCheckedNodes]

      console.log('提交的权限节点:', {
        checked: checkedNodes,
        halfChecked: halfCheckedNodes,
        all: allCheckedNodes
      })
      data.roleId = currentRole.value.id;
      data.permissionIds = allCheckedNodes;
      const response = await assignRolePermissionsAPI(data)

      if (response.code === 200) {
        ElMessage.success('权限分配成功')
        permissionDialogVisible.value = false
      } else {
        ElMessage.error(response.message)
      }
    } catch (error) {
      console.error('权限分配失败:', error)
      ElMessage.error('权限分配失败')
    } finally {
      permissionSubmitLoading.value = false
    }
  }

  // 生命周期
  onMounted(() => {
    getRoleList()
  })
</script>

<style scoped>
  .role-container {
    padding: 20px;
  }

  .search-card {
    margin-bottom: 20px;
  }

  .search-form {
    margin-bottom: 0;
  }

  .main-card {
    min-height: 600px;
  }

  .card-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
  }

  .card-header h3 {
    margin: 0;
    color: #333;
  }

  .header-buttons {
    display: flex;
    gap: 10px;
  }

  .pagination-container {
    margin-top: 20px;
    display: flex;
    justify-content: flex-end;
  }

  .role-form {
    padding: 0 20px;
  }

  .dialog-footer {
    display: flex;
    justify-content: flex-end;
    gap: 10px;
  }

  .permission-dialog-content {
    max-height: 500px;
  }

  .permission-info {
    background-color: #f5f7fa;
    padding: 15px;
    border-radius: 6px;
    margin-bottom: 15px;
  }

  .permission-info p {
    margin: 0 0 8px 0;
    color: #606266;
  }

  .permission-info p:last-child {
    margin-bottom: 0;
  }

  .permission-tree-container {
    max-height: 350px;
    overflow-y: auto;
  }

  .permission-tree-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 15px;
    padding-bottom: 10px;
    border-bottom: 1px solid #e4e7ed;
  }

  .permission-tree-header span {
    font-weight: 600;
    color: #303133;
  }

  .tree-actions {
    display: flex;
    gap: 8px;
  }

  .permission-tree {
    border: 1px solid #e4e7ed;
    border-radius: 4px;
    padding: 10px;
  }

  .tree-node {
    display: flex;
    align-items: center;
    gap: 6px;
    flex: 1;
  }

  .node-icon {
    color: #409eff;
  }

  .node-label {
    flex: 1;
  }

  .node-tag {
    margin-left: 8px;
  }

  /* 响应式设计 */
  @media (max-width: 768px) {
    .role-container {
      padding: 10px;
    }

    .search-form {
      flex-direction: column;
    }

    .search-form .el-form-item {
      margin-right: 0;
      margin-bottom: 15px;
    }

    .card-header {
      flex-direction: column;
      align-items: flex-start;
      gap: 15px;
    }

    .header-buttons {
      width: 100%;
      justify-content: flex-start;
    }

    .tree-actions {
      flex-wrap: wrap;
    }
  }
</style>
